import { combineResolvers } from 'graphql-resolvers'
import { pageModel } from '../../lib/helper'
import auth from '../../middlewares/auth'
import { userLoader } from '../user/dataloaders'

module.exports = {
  Query: {
    group: combineResolvers(
      async (root, { id }, { models: { Group } }) => {
        const result = await Group.findById(id)
        return result
      },
    ),
    allGroups: async (root, { pageIndex, pageSize }, { models: { Group } }) => {
      const result = await Group.findAndCountAll({
        offset: pageIndex * pageSize,
        limit: pageSize
      })
      let t = pageModel(result, pageIndex, pageSize)
      return t
    },
    groups: combineResolvers(
      auth,
      async (root, { pageIndex, pageSize }, { services: { $group }, user }) => {
        const result = await $group.findMyClasses({
          userId: user.id,
          pageIndex,
          pageSize
        })
        return pageModel(result, pageIndex, pageSize)
      }
    ),
    groupMys: combineResolvers(
      auth,
      async (root, { pageIndex, pageSize }, { models: { Group }, user }) => {
        let groups = await Group.findAll({
          where: {
            ownerId: user.id,
            state: 'normal'
          },
          order: [['id', 'desc']]
        })
        return groups
      }
    ),
    groupMyRelates: combineResolvers(
      auth,
      async (root, { pageIndex, pageSize }, { models: { Group, UserGroup }, user }) => {
        let ugs = await UserGroup.findAll({
          where: {
            userId: user.id
          }
        })
        let gids = ugs.map(n => n.groupId)

        let groups = await Group.findAll({
          where: {
            id: gids
          },
          order: [['id', 'desc']]
        })
        return groups
      }
    ),
    groupMyGroupInfo: combineResolvers(
      auth,
      async (root, { groupId }, { models: { UserGroup }, user }) => {
        let ug = await UserGroup.findOne({
          where: {
            groupId,
            userId: user.id
          }
        })
        return ug
      }
    )
  },
  Mutation: {
    wxGroupInfo: combineResolvers(
      auth,
      async (
        root,
        { encryptedData, iv, groupOwnerId = 0 },
        { services: { $wechat, $group }, user }
      ) => {
        let userId = user.id
        let groupInfo = await $wechat.decryptInfo(encryptedData, iv, userId)
        const openGroupId = groupInfo.openGId
        return await $group.findAndJoin(openGroupId, userId, groupOwnerId)
      }
    ),
    groupCreate: combineResolvers(
      auth,
      async (root, { name }, { models: { Group }, user }) => {
        let userId = user.id
        let count = await Group.count({
          where: {
            ownerId: userId,
            name,
            state: {$ne: 'disbanded'}
          }
        })
        if (count > 0) throw new Error('相同名称的班级已存在')
        let group = await Group.create({
          source: 'user',
          ownerId: userId,
          name
        })
        return group
      }
    ),
    groupModify: combineResolvers(
      auth,
      async (root, { groupId, name }, { models: { Group }, user }) => {
        let userId = user.id

        let count = await Group.count({
          where: {
            id: {$ne: groupId},
            ownerId: userId,
            name,
            state: {$ne: 'disbanded'}
          }
        })
        if (count > 0) throw new Error('相同名称的班级已存在')

        let group = await Group.findById(groupId, {where: {
          ownerId: userId
        }})
        group.name = name
        await group.save()
        return group
      }
    ),
    groupJoin: combineResolvers(
      auth,
      async (
        root,
        { groupId, name, role },
        { models: { Group, UserGroup }, user }
      ) => {
        let userId = user.id
        let group = await Group.findById(groupId)
        let count = await UserGroup.count({
          where: {
            groupId,
            userId
          }
        })
        if (count) return true

        let ug = await UserGroup.findOne({
          where: {
            groupId,
            name
          }
        })
        let relateId = 0
        if (ug) {
          relateId = ug.userId
        }

        await UserGroup.create({
          name,
          role,
          groupId,
          userId,
          relateId
        })
        return true
      }
    ),
    groupModifyMemberInfo: combineResolvers(
      auth,
      async (
        root,
        { groupId, name },
        { models: { Group, UserGroup }, user }
      ) => {
        let userId = user.id
        let ug = await UserGroup.findOne({
          where: {
            groupId,
            userId
          }
        })
        if (!ug) throw new Error(`${ERRORS.DBERR.ERR_RECORD_NOT_FOUND}`)
        ug.name = name
        await ug.save()
        return true
      }
    ),
    groupRemoveMembersByIds: combineResolvers(
      auth,
      async (
        root,
        { groupId, memberIds },
        { models: { Group, UserGroup }, user }
      ) => {
        await UserGroup.destroy({
          where: {
            groupId,
            userId: memberIds
          },
          force: true
        })
        return true
      }
    ),
    groupDisband: combineResolvers(
      auth,
      async (
        root,
        { groupId },
        { models: { Group, UserGroup }, user }
      ) => {
        let group = await Group.findById(groupId)
        group.state = 'disbanded'
        await group.save()
        return true
      }
    ),
    generateAvatar: async (
      root,
      { id },
      { services: { $group_avatar_mq } }
    ) => {
      const result = await $group_avatar_mq.generateAvatar(id)
      return result
    }
  },
  Group: {
    owner: async ({ ownerId }, data, { models: { User } }) => {
      if (!ownerId) return null
      let user = await User.findById(ownerId)
      return user
    },
    users: async ({ id }, data, { services: { $group } }) => {
      let result = await $group.findGroupStudents(id, [], 10000)
      return result
    },
    members: async ({ id }, data, { services: { $group } }) => {
      let members = await $group.getMembers(id, 10000)
      return members
    }
  },
  Member: {
    roleName: async ({ role }) => {
      let kvRoleName = {
        'user': '本人',
        'father': '爸爸',
        'mather': '妈妈'
      }
      return kvRoleName[role] || ''
    }
  }
}
